import java.util.ArrayList;
import java.util.List;

/**
 * 113. 路径总和 II（与 剑指 Offer 34 同）
 * https://leetcode-cn.com/problems/path-sum-ii/
 */
public class Solutions_113 {
    public static void main(String[] args) {
        TreeNode root = new TreeNode(5);
        root.left = new TreeNode(4);
        root.left.left = new TreeNode(11);
        root.left.left.left = new TreeNode(7);
        root.left.left.right = new TreeNode(2);
        root.right = new TreeNode(8);
        root.right.left = new TreeNode(13);
        root.right.right = new TreeNode(4);
        root.right.right.left = new TreeNode(5);
        root.right.right.right = new TreeNode(1);
        int sum = 22;  // output: {{5, 4, 11, 2}, {5, 8, 4, 5}}

        List<List<Integer>> result = pathSum(root, sum);
        System.out.println(result);
    }

    public static List<List<Integer>> pathSum(TreeNode root, int sum) {
        // 结果集：从根节点到叶子节点的路径和等于 sum 的路径节点列表
        List<List<Integer>> res = new ArrayList<>();
        // 递归 root 过程中，用于记录路径节点的列表
        List<Integer> list = new ArrayList<>();

        pathSum_dfs(root, sum, res, list);
        return res;
    }

    public static void pathSum_dfs(TreeNode root, int sum, List<List<Integer>> res,
                                   List<Integer> list) {
        if (root == null) {
            return;
        }
        // 添加一个当前节点到“路径”中
        list.add(root.val);
        if (root.left == null && root.right == null && sum == root.val) {
            // 添加结果集：当前节点为叶子节点，且从根路径到当前节点的和正好等于 sum
            res.add(new ArrayList<>(list));
        }
        // 递归左右子树，剩余的 sum 就是 sum - root.val
        pathSum_dfs(root.left, sum - root.val, res, list);
        pathSum_dfs(root.right, sum - root.val, res, list);
        // 当前节点的左右子树都遍历完了，不管路径和是不是等于 sum，都需要进行 remove 操作，回溯到上一级
        list.remove(list.size() - 1);
    }
}
